/// **************************************************************************************************
/// "Copyright (c) 2007 Sai Panyam, Inc.  All rights reserved."
/// **************************************************************************************************
/// Component Name   :	PhraseModifier, Member of System72.NTextile 
/// Description      :	PhraseModifier description
/// Author           :	Sai Panyam
/// Creation Date    :	November 09 2007
/// Modified Date    :              
/// Modified By      :
/// **************************************************************************************************
using System;
using System.Text.RegularExpressions;
using System72.NTextile.RegexLibrary;

namespace System72.NTextile
{
    /// <summary>
    /// 
    /// </summary>
    internal class PhraseModifier : IModifier
    {
        #region Private Variables

        private readonly PhraseModifierType m_phraseModifierType;
        private readonly Operation m_operation;
        private AttributeCollection m_supportedAttributes;
        private PunctuationCollection m_supportedPunctuations;
        private bool m_success;
        private readonly int m_parseOrder=2;
        private readonly ModifierType m_type;
        
        #endregion

        #region Constructor
        /// <summary>
        /// 
        /// </summary>
        /// <param name="phraseModifierType"></param>
        public PhraseModifier(PhraseModifierType phraseModifierType)
        {
            m_phraseModifierType = phraseModifierType;
            OperationFactory factory = new OperationFactory(m_phraseModifierType);
            m_operation = factory.GetPhraseOperation();
            m_type = m_operation.ModifierType;
        }

        #endregion
        
        #region Public Properties
        /// <summary>
        /// 
        /// </summary>
        public PhraseModifierType PhraseModifierType
        {
            get
            {
                return m_phraseModifierType;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public string Tag
        {
            get
            {
                return (m_operation!=null)?m_operation.Tag:String.Empty;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public string Operator
        {
            get
            {
                return (m_operation != null) ? m_operation.Operator : String.Empty;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public Operation Operation
        {
            get
            {
                return m_operation;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public AttributeCollection SupportedAttributes
        {
            get
            {
                return m_supportedAttributes;
            }
            set
            {
                m_supportedAttributes = value;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public PunctuationCollection SupportedPunctuations
        {
            get { return m_supportedPunctuations; }
            set { m_supportedPunctuations = value; }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool Success
        {
            get { return m_success; }
            set { m_success = value; }
        }
        /// <summary>
        /// 
        /// </summary>
        public int ParseOrder
        {
            get { return m_parseOrder; }
        }
        /// <summary>
        /// 
        /// </summary>
        public ModifierType Type
        {
            get { return m_type; }
        }

        #endregion

        #region Public Methods
        /// <summary>
        /// 
        /// </summary>
        /// <param name="contentText"></param>
        /// <param name="excludedModifiers"></param>
        /// <returns></returns>
        public string GetXHTML(string contentText, ModifierCollection excludedModifiers)
        {
            if (m_operation != null)
            {
                if (!excludedModifiers.ContainsModifier(this))
                {
                    PhraseRegex phraseRegEx = new PhraseRegex(m_operation.RegExOperator, m_operation.Operator);
                    MatchCollection matchCollection = phraseRegEx.GetMatches(contentText);
                    foreach (Match match in matchCollection)
                    {
                        //Do the HTML only if any content is present between the operators
                        if (match.Value.Length > (m_operation.Operator.Length*2))
                        {
                            //Since there is atleast one match then we can set Success to true
                            m_success = true;
                            string matchText = match.Value;//.Replace(m_operation.Operator, "");
                            //First remove the operator and the enclosed text before parsing for 
                            //punctuation
                            contentText = contentText.Replace(matchText, "[matchText]");
                            string finalAttribute = String.Empty;
                            if (m_type !=ModifierType.DeletedText)//Since the "-" will trigger the emDash or enDash punctuation
                            {
                                contentText = parseForPunctuations(contentText);
                            }
                            //Do the Attributes after parsing for punctuation as
                            //we don't want it to parse the 'doublequotes' etc in the attribute definition
                            //Remove the operators from the matched text
                            matchText = matchText.Replace(m_operation.Operator, String.Empty);
                            matchText = parseForAttributes(matchText, ref finalAttribute);
                            matchText = Util.GetElementMarkUp(matchText, m_operation.Tag, finalAttribute);
                            contentText = contentText.Replace("[matchText]", matchText);
                        }
                    }
                }
            }
            return contentText;
        }

        #endregion

        #region Private Methods
        /// <summary>
        /// 
        /// </summary>
        /// <param name="matchText"></param>
        /// <returns></returns>
        private string parseForPunctuations(string matchText)
        {
            if (m_supportedPunctuations != null && m_supportedPunctuations.Count > 0)
            {
                foreach (Punctuation punctuation in m_supportedPunctuations)
                {
                    matchText = punctuation.GetModifiedText(matchText);
                }
            }
            return matchText;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="matchText"></param>
        /// <param name="finalAttribute"></param>
        /// <returns></returns>
        private string parseForAttributes(string matchText, ref string finalAttribute)
        {
            if (m_supportedAttributes != null && m_supportedAttributes.Count > 0)
            {
                foreach (Attribute attribute in m_supportedAttributes)
                {
                    string matchValue;
                    string attributeValue = m_operation.GetAttributeText(matchText, attribute, out matchValue);
                    attribute.AttributeValue = attributeValue;
                    string attributeKeyValue = attribute.GetAttributeKeyValueText();
                    if (matchValue == String.Empty)
                    {
                        attributeKeyValue = String.Empty;
                    }
                    else
                    {
                        matchText = matchText.Replace(matchValue, "");
                    }
                    finalAttribute = finalAttribute + attributeKeyValue;
                }
            }
            return matchText;
        }
        #endregion
    }
}
